/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "ui数值部件.h"
#include "ui标量部件.h"

#include "core/属性.h"
#include "core/shader_binding_ID.h"
#include "core/shader_curve.h"
#include "core/引擎配置.h"
#include "core/动画/curve.h"




static uint16 g滚动条变换绘制ID = 0;
static uint16 g滚动条颜色绘制ID = 0;
static uint16 g滚动条边颜色绘制ID = 0;





static float32 g_手臂越界距离 = 0.0f;



static bool on_手柄按键按下(C_Widget* self, const E_鼠标按钮& 按钮) {


	return true;
}

static E_事件是否传递 on_数值滚动条手柄拖动(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	C_滚动条* 滚动条 = dynamic_cast<C_滚动条*>(self->m_父部件);
	float32 滚动条在条中比例 = 0;

	if (滚动条->m_排列方向 == E_方向::e_纵向) {
		self->f_setY(self->m_Pos.y + 鼠标.abs.y);
		if (self->m_Pos.y < 0) self->f_setY(0);
		else if (self->m_Pos.y + self->m_Size.y > 滚动条->m_Size.y) self->m_Pos.y = 滚动条->m_Size.y - self->m_Size.y;

		滚动条在条中比例 = self->m_Pos.y / (滚动条->m_Size.y - self->m_Size.y + 0.00000001);

	}
	else {
		self->f_setX(self->m_Pos.x + 鼠标.abs.x);
		if (self->m_Pos.x < 0) self->f_setX(0);
		else if (self->m_Pos.x + self->m_Size.x > 滚动条->m_Size.x) self->m_Pos.x = 滚动条->m_Size.x - self->m_Size.x;
	}

	滚动条->f_计算绑定的值(滚动条在条中比例);
	滚动条->m_父部件->m_绘制属性更新 = true;
	if (滚动条->mf_滑块滚动回调) 滚动条->mf_滑块滚动回调(滚动条, 滚动条->m_值);
	return E_事件是否传递::e_事件传递_终止;
}
static vec2 鼠标位置记录;
static E_事件是否传递 on_数值滚动条手柄开始拖拽(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	C_滚动条* 滚动条 = dynamic_cast<C_滚动条*>(self->m_父部件);
	if (滚动条->m_排列方向 == E_方向::e_纵向) {
		self->f_setY(self->m_Pos.y + 鼠标.abs.y);
	}
	else {
		self->f_setX(self->m_Pos.x + 鼠标.abs.x);
	}

	鼠标位置记录 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);
	
	return E_事件是否传递::e_事件传递_继续;
}

static bool on_数值滚动条手柄结束拖拽(C_Widget* self, C_Widget* 拾取的部件, S_拖放数据& data) {
	C_滚动条* 滚动条 = dynamic_cast<C_滚动条*>(self->m_父部件);
	if (滚动条->m_排列方向 == E_方向::e_纵向) {
		if (self->m_Pos.y < 0) self->f_setY(0);
	}
	else {
		if (self->m_Pos.x < 0) self->f_setX(0);
	}
	
	鼠标位置记录.x += self->m_GlobalLoc.x + C_Widget::g_鼠标.相对窗口偏移.x;
	鼠标位置记录.y += self->m_GlobalLoc.y + C_Widget::g_鼠标.相对窗口偏移.y;
	f_widget_set鼠标位置(&鼠标位置记录);
	鼠标位置记录 = {};
	return true;
}



static void f_单向滚动条布局(C_Widget* r, C_Widget** w, uint32 num) {
	C_滚动条* 滚动条 = dynamic_cast<C_滚动条*>(r);
	
	vec2 loc = {};
	vec2 size = {};

	float32 手柄长度 = 滚动条->f_计算手柄长度();
	
	if (num == 1) {
		if (滚动条->m_滑块自适应大小) {
			switch (滚动条->m_排列方向)
			{
			case E_方向::e_横向: {
				size.x = 手柄长度;
				size.y = 滚动条->m_Size.y;
			}
						   break;
			case E_方向::e_纵向: {
				size.x = 滚动条->m_Size.x;
				size.y = 手柄长度;
			}
						   break;
			default:
				break;
			}
		}
		else {
			switch (滚动条->m_排列方向)
			{
			case E_方向::e_横向: {
				size.x = 滚动条->m_Size.y;
				size.y = 滚动条->m_Size.y;
			}
						   break;
			case E_方向::e_纵向: {
				size.x = 滚动条->m_Size.x;
				size.y = 滚动条->m_Size.x;
			}
						   break;
			default:
				break;
			}
			
		}

		w[0]->f_setSize(size);
		//w[0]->f_setLoc(loc);
	}
	else if (num == 3) {

	}

}

C_滚动条::C_滚动条(S_UI创建环境& ctx, E_方向 dir, C_Widget* 按钮[3]) : m_排列方向(dir) {
	m_颜色A = S_UI主题::uic_滚动条;

	m_值比例 = 0.0;
	m_值区间 = { 0,1 };
	mf_滑块滚动回调 = nullptr;
	m_滑块自适应大小 = false;

	mf_布局Fun	= f_单向滚动条布局;
	m_映射位置 = nullptr;

	if (按钮) {
		for (uint8 i = 0; i < 3; ++i) {
			if (按钮[i]) {
				//f_添加子组件(按钮[i]);
			}
		}
	}

	m_滑块 = new C_Widget();
	m_滑块->m_颜色A = S_UI主题::uic_滚动条按钮;
	m_滑块->mf_拖拽 = on_数值滚动条手柄拖动;
	m_滑块->mf_开始拖拽 = on_数值滚动条手柄开始拖拽;
	m_滑块->mf_结束拖拽 = on_数值滚动条手柄结束拖拽;
	m_滑块->mf_鼠标按键按下;
	f_添加子组件(m_滑块);
}

C_滚动条::~C_滚动条() {
}

float32 C_滚动条::f_getValue() {

	return float32();
}

void C_滚动条::f_滚动滑块(float32 d) {
}

float32 C_滚动条::f_计算手柄长度() {
	float32 手柄长度 = m_值区间.y - m_值区间.x;

	
	//if (!m_映射最大值) return DEF_Min(m_Size.x, m_Size.y);
	switch (m_排列方向) {
	case E_方向::e_横向:
		手柄长度 = (m_Size.x - m_Size.y) / 手柄长度;
		return DEF_Min(m_Size.y, 手柄长度) * m_Size.x;

	case E_方向::e_纵向:
		手柄长度 = (m_Size.y - m_Size.x) / 手柄长度;
		return DEF_Min(m_Size.x, 手柄长度) * m_Size.y;
	}

	return 手柄长度;
}

void C_滚动条::f_计算绑定的值(float32 滚动条在条中比例) {
	m_值 = (m_值区间.y - m_值区间.x) * 滚动条在条中比例;
	//if(m_映射位置) (*m_映射位置) = m_值;
	//std::cout << "(*m_映射位置) = " << (*m_映射位置) << "  " << m_值 << std::endl;
}

void C_滚动条::f_从绑定部件更新滑块() {
	float32 滚动条在条中比例 = (*m_映射位置) / (m_值区间.y - m_值区间.x);

	switch (m_排列方向)
	{
	case E_方向::e_横向:
		m_滑块->f_setX(-(m_Size.x - m_滑块->m_Size.x) * 滚动条在条中比例);
		return ;

	case E_方向::e_纵向:
		m_滑块->f_setY(-(m_Size.y - m_滑块->m_Size.y) * 滚动条在条中比例);
		return ;
	}
	
}














S_双向滚动条::S_双向滚动条(float32 厚度, C_Widget* 父部件, S_UI创建环境& ctx, C_Widget* 按钮[2]) {
	m_V = new C_滚动条(ctx, E_方向::e_纵向);
	m_H = new C_滚动条(ctx, E_方向::e_横向);

	m_V->f_setSize({ 厚度 , 厚度 });
	m_H->f_setSize({ 厚度 , 厚度 });

	父部件->f_添加子组件(m_V);
	父部件->f_添加子组件(m_H);


}

S_双向滚动条::~S_双向滚动条() {
	
}




std::vector<uint16> f_draw_双向滚动条(C_Widget* 部件, S_2D画布* 画布, float32 厚度) {
	return {};
	std::vector<uint16> id;
	//g滚动条变换绘制ID = f_vg_gen变换(画布, 4);
	//g滚动条颜色绘制ID = f_vg_gen颜色(画布, 4);
	auto p = f_vg_gen属性(画布);

	//auto pen = f_vg_gen单色填充(画布, g滚动条变换绘制ID, g滚动条颜色绘制ID, p);

	//auto e0 = f_vg_绘制圆角矩形(画布, pen, { 0.0f, 0.0f, 1.0f, 1.0f }, 厚度/2, true);

	
	f_vg_set单色(画布, g滚动条颜色绘制ID, 0, S_UI主题::uic_滚动条);
	f_vg_set单色(画布, g滚动条颜色绘制ID, 1, S_UI主题::uic_滚动条);
	f_vg_set单色(画布, g滚动条颜色绘制ID, 2, S_UI主题::uic_滚动条按钮);
	f_vg_set单色(画布, g滚动条颜色绘制ID, 3, S_UI主题::uic_滚动条按钮);



	//g滚动条边颜色绘制ID = f_vg_gen颜色(画布, 2);
	f_vg_set单色(画布, g滚动条边颜色绘制ID, 0, S_UI主题::uic_面板边);
	f_vg_set单色(画布, g滚动条边颜色绘制ID, 1, S_UI主题::uic_面板边);

	return { g滚动条变换绘制ID , g滚动条颜色绘制ID, g滚动条边颜色绘制ID };
}












static void f_VecDraw(C_Widget* self, S_2D画布* 画布) {
	C_Vec* v = (C_Vec*)(self);

	v->m_draw属性ID = f_vg_gen属性(画布);
	f_vg_set属性(画布, v->m_draw属性ID, { 1,1 }, { 0,0 }, 0, 2);
	//v->m_draw.f_Draw(画布, v->m_draw属性ID, self->m_UIctx->m_文字字号);
	//auto 字体 = f_surface_get字体(*self->m_UIctx, S_UI主题::ui_默认字体);
	//v->m_文本绘制.f_Draw(画布, &字体, v->m_draw属性ID);

}

static void f_setVec变换修改(C_Widget* self) {
	C_Vec* v = (C_Vec*)(self);

	auto e = self->f_get更新部件();
	
	uint32 每行字符数量 = 10;
	uint32 num = v->m_Value.m_值元素个数;

	//v->m_文本绘制.f_Begin(num, 每行字符数量);

	for (uint16 i = 0; i < num; ++i) {
		//f_ui_get属性到文本(v->m_Value,)
		//v->m_文本绘制.f_绘制文本({ {0, e.m_W[i]->m_Pos.y}, {20, e.m_W[i]->m_Size.y} }, S_UI主题::uic_文字颜色, i, v->m_标签[i], E_对齐方式::e_右对齐);
	}

	//v->m_文本绘制.f_End();
}

static void f_Vec布局(C_Widget* r, C_Widget** w, uint32 num) {
	C_Vec* vec = dynamic_cast<C_Vec*>(r);

	vec2 loc = {};
	//loc.x = r->m_间隔宽度;
	//loc.y = r->m_间隔宽度;
	//vec2 size = { r->m_Size.x - r->m_间隔宽度 * 2, r->m_Size.y - r->m_间隔宽度 * 2 };
	vec2 size = r->m_Size;
	
	if (num) {
		switch (vec->m_方向)
		{
		case E_方向::e_横向:
			f_HBOX布局({0, 0}, size, w, num);
			break;
		case E_方向::e_纵向:
			f_VBOX布局({0, 0}, size, w, num);
			break;
		default:
			break;
		}
	}
}

static bool f_vec部件开启编辑(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_Vec* vec = dynamic_cast<C_Vec*>(self);
}
static void on_vec编辑框当前输入(C_Widget* self, std::wstring& text) {
	C_Vec* vec = dynamic_cast<C_Vec*>(self);
}
static void on_vec编辑框输入完成(C_Widget* self) {
	C_Vec* vec = dynamic_cast<C_Vec*>(self);
}

C_Vec::C_Vec(E_方向 dir, S_Props& Value, S_UI创建环境& ctx) : C_Widget(&ctx){
	m_方向 = dir;
	mf_布局Fun = f_Vec布局;
	mf_DrawFun = f_VecDraw;
	mf_变换修改 = f_setVec变换修改;

	m_颜色A = S_UI主题::uic_值编辑框背景;
	m_颜色B = S_UI主题::uic_值编辑框边;

	m_Value = Value;
	m_Value.m_UI->m_部件 = this;

	m_标签 = { L"x:", L"y:", L"z:", L"w:" };

	float32 h = 0;
	for (uint8 i = 0; i < Value.m_值元素个数; ++i) {
		C_数值编辑框* box = new C_数值编辑框(ctx, Value, i);
		box->m_是否延展 = {true, true};
		box->m_间隔宽度 = 1;
		box->m_图元 = S_Widget预设图元::m_矩形;
		
		box->m_实例ID = i;
		box->m_标签 = m_标签[i];
		f_添加子组件(box);

		h += 24;
	}
	f_setH(h);
	f_切换布局方向(m_方向);
}

C_Vec::~C_Vec() {
}

void C_Vec::f_切换布局方向(E_方向 方向) {
	m_方向 = 方向;

	if (m_子组件.size() >= 2) {
		if (m_方向 == E_方向::e_纵向) {
			((C_数值编辑框*)m_子组件[0])->m_图元 = S_Widget预设图元::m_上圆角矩形;
			((C_数值编辑框*)(m_子组件.back()))->m_图元 = S_Widget预设图元::m_下圆角矩形;
		}
		else {
			((C_数值编辑框*)m_子组件[0])->m_图元 = S_Widget预设图元::m_左圆角矩形;
			((C_数值编辑框*)(m_子组件.back()))->m_图元 = S_Widget预设图元::m_右圆角矩形;
		}

	}
}


void f_ui_设置vec编辑框引用值(C_Widget* w, S_Props prop) {
	auto* view = dynamic_cast<C_Vec*>(w);
	if (view) {
		view->m_Value = prop;
		f_widget_remove所有子部件(w, false);

		float32 h = 0;
		for (uint8 i = 0; i < prop.m_值元素个数; ++i) {
			C_数值编辑框* box = new C_数值编辑框(*w->m_UIctx, view->m_Value, i);
			box->m_是否延展 = {true, true};
			box->m_间隔宽度 = 1;
			box->m_图元 = S_Widget预设图元::m_矩形;

			box->m_实例ID = i;
			box->m_标签 = view->m_标签[i];
			view->f_添加子组件(box);

			h += 24;
		}
		view->f_setH(h);
		view->f_切换布局方向(view->m_方向);


		auto e = w->f_get更新部件();
		for (uint8 i = 0; i < prop.m_值元素个数; ++i) {
			switch (view->m_Value.m_Type)
			{
			case E_值类型::e_Type_RGB:
			case E_值类型::e_Type_Vec2:
			case E_值类型::e_Type_Vec3:
			case E_值类型::e_Type_Vec4:{
				float32* v = ((float32*)view->m_Value.m_Value);
				dynamic_cast<C_数值编辑框*>(e.m_W[i])->m_Text = f_浮点数值转宽字符串(v[i]);
				break;
			}
			case E_值类型::e_Type_uVec2:
			case E_值类型::e_Type_uVec3:
			case E_值类型::e_Type_uVec4:
				dynamic_cast<C_数值编辑框*>(e.m_W[i])->m_Text = f_整数值转宽字符串(((uint32*)view->m_Value.m_Value)[i]);
				break;

			case E_值类型::e_Type_iVec2:
			case E_值类型::e_Type_iVec3:
			case E_值类型::e_Type_iVec4:
				dynamic_cast<C_数值编辑框*>(e.m_W[i])->m_Text = f_整数值转宽字符串(((int32*)view->m_Value.m_Value)[i]);
				break;
			default:
				break;
			}

			dynamic_cast<C_数值编辑框*>(e.m_W[i])->m_Value = prop;
		}
	}
}

void f_ui_刷新vec编辑框文本绘制(C_Widget* w) {
	if (C_文本框::g当前操作文本框) return;

	auto* view = dynamic_cast<C_Vec*>(w);

	auto e = w->f_get更新部件();
	for (uint8 i = 0; i < view->m_Value.m_值元素个数; ++i) {
		switch (view->m_Value.m_Type)
		{
		case E_值类型::e_Type_RGB:
		case E_值类型::e_Type_Vec2:
		case E_值类型::e_Type_Vec3:
		case E_值类型::e_Type_Vec4: {
			float32* v = ((float32*)view->m_Value.m_Value);
			dynamic_cast<C_数值编辑框*>(e.m_W[i])->m_Text = f_浮点数值转宽字符串(v[i]);
			break;
		}
		case E_值类型::e_Type_uVec2:
		case E_值类型::e_Type_uVec3:
		case E_值类型::e_Type_uVec4:
			dynamic_cast<C_数值编辑框*>(e.m_W[i])->m_Text = f_整数值转宽字符串(((uint32*)view->m_Value.m_Value)[i]);
			break;

		case E_值类型::e_Type_iVec2:
		case E_值类型::e_Type_iVec3:
		case E_值类型::e_Type_iVec4:
			dynamic_cast<C_数值编辑框*>(e.m_W[i])->m_Text = f_整数值转宽字符串(((int32*)view->m_Value.m_Value)[i]);
			break;
		default:
			break;
		}

		e.m_W[i]->m_绘制属性更新 = true;
	}

	
}










static void on_多选框Draw(C_Widget* self, S_2D画布* 画布) {
	C_多选框* box = (C_多选框*)(self);

	box->m_背景绘制.m_属性 = f_vg_gen属性(画布);
	
	S_凸边图元 图元 = {};
	图元.属性 = f_vg_get属性指针(画布, box->m_背景绘制.m_属性);
	//if (box->m_Value.m_UI->m_部件) {
	//	C_多选框* box_link = dynamic_cast<C_多选框*>(box->m_Value.m_UI->m_部件);
	//	图元.颜色 = box_link->m_背景绘制.m_图元.颜色;
	//}
	box->m_背景绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色填充);

	auto 字体 = f_surface_get字体(*self->m_UIctx, S_UI主题::ui_默认字体);
	box->m_文本绘制.f_Draw(画布, &字体, box->m_背景绘制.m_属性);
	box->m_图标绘制.f_Draw单色(画布, box->m_背景绘制.m_属性, S_UI主题::ui_默认图标);

}

static void on_多选框变换修改(C_Widget* self) {
	C_多选框* box = (C_多选框*)(self);

	auto ws = self->f_get更新部件();


	switch (box->m_Value.m_Type) {
	case E_值类型::e_Type_Bool_1D: {
		auto e = f_prop_Bool_1D(box->m_Value);

		box->m_背景绘制.f_alloc(ws.m_Num+1);
		box->m_文本绘制.f_alloc(box->m_Value.m_值元素个数, 10);
		box->m_图标绘制.f_alloc(box->m_Value.m_值元素个数);

		mat3X2 Mat;
		box->m_背景绘制.f_set单色填充(0, { {}, self->m_Size, {S_UI主题::ui_面板圆角半径,0}}, S_UI主题::uic_深灰, S_Widget预设图元::m_圆角矩形);
		for (uint32 i = 0; i < box->m_Value.m_值元素个数; ++i) {
			Mat.row0 = ws.m_W[i]->m_Pos;
			Mat.row1 = ws.m_W[i]->m_Size;
			Mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };

			if (e[i].m_Value) {
				box->m_背景绘制.f_set单色填充(i+1, Mat, S_UI主题::uic_菜单焦点色, ws.m_W[i]->m_图元);
			}
			else {
				box->m_背景绘制.f_set单色填充(i+1, Mat, box->m_颜色A, ws.m_W[i]->m_图元);
			}

			if (box->m_是否绘制标题) {
				box->m_文本绘制.f_居中绘制文本({ Mat.row0 , Mat.row1 }, S_UI主题::uic_文字颜色, i, e[i].m_Names);
			}
			if (box->m_是否绘制图标) {
				Mat.row0 = ws.m_W[i]->m_Pos + ws.m_W[i]->m_Size.y * 0.5f;
				Mat.row1.x = ws.m_W[i]->m_Size.y * 0.8f;
				box->m_图标绘制.f_set(e[i].m_ICO, i, Mat, S_UI主题::uic_文字颜色);
			}
		}
		break;
	}

	case E_值类型::e_Type_UI32_FlagBits: {
		auto e = f_prop_UI32(box->m_Value);

		box->m_背景绘制.f_alloc(ws.m_Num + 1);
		box->m_文本绘制.f_Close();
		box->m_图标绘制.f_Close();

		mat3X2 Mat;
		Mat.row0 = {0,0};
		Mat.row1 = self->m_Size;
		Mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
		box->m_背景绘制.f_set单色填充(0, Mat, S_UI主题::uic_深灰, S_Widget预设图元::m_圆角矩形);

		for (uint32 i = 0; i < ws.m_Num; ++i) {
			Mat.row0 = ws.m_W[i]->m_Pos;
			Mat.row1 = ws.m_W[i]->m_Size;
			Mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };

			if (e & 1<<i) {
				box->m_背景绘制.f_set单色填充(i+1, Mat, S_UI主题::uic_菜单焦点色, ws.m_W[i]->m_图元);
			}
			else {
				box->m_背景绘制.f_set单色填充(i+1, Mat, box->m_颜色A, ws.m_W[i]->m_图元);
			}
		}
		break;
	}
	default:
		break;
	}

	
}

static void on_多选框布局(C_Widget* self, C_Widget** w, uint32 num) {
	if (!num) return;
	C_多选框* box = (C_多选框*)(self);

	vec2 loc = {};
	vec2 size = self->m_Size;
	
	switch (box->m_Value.m_Type) {
	case E_值类型::e_Type_Bool_1D: {
		
		switch (box->m_方向)
		{
		case E_方向::e_横向:
			size.x -= 4;
			f_HBOX布局({ 1.5f, 1.5f }, size, w, num);
			break;
		case E_方向::e_纵向:
			size.x -= 4;
			f_VBOX布局({1.5f, 1.5f}, size, w, num);
			break;
		default:
			break;
		}
		
		break;
	}
	case E_值类型::e_Type_UI32_FlagBits: {
		f_Layout_网格(self, w, num, 8, 4);
		break;
	}
	default:
		break;
	}


	size.x -= self->m_间隔宽度;
	
}

static bool on_鼠标进入项(C_Widget* self, const S_鼠标& 鼠标) {
	C_多选框* box = (C_多选框*)(self->m_父部件);

	switch (box->m_Value.m_Type) {
	case E_值类型::e_Type_Bool_1D: {
		auto e = f_prop_Bool_1D(box->m_Value);
		if (e[self->m_实例ID].m_Value == false) {
			box->m_背景绘制.f_setColor(self->m_实例ID + 1, box->m_颜色A + S_RGBA8UI{ 20,20,20,0 });
		}
		break;
	}
	case E_值类型::e_Type_UI32_FlagBits: {
		auto e = f_prop_UI32(box->m_Value);
		if ( (e & 1<<self->m_实例ID) == false) {
			box->m_背景绘制.f_setColor(self->m_实例ID+1, box->m_颜色A + S_RGBA8UI{ 20,20,20,0 });
		}
		break;
	}
	}

	
	return false;
}
static bool on_鼠标离开项(C_Widget* self, const S_鼠标& 鼠标) {
	C_多选框* box = (C_多选框*)(self->m_父部件);

	switch (box->m_Value.m_Type) {
	case E_值类型::e_Type_Bool_1D: {
		auto e = f_prop_Bool_1D(box->m_Value);
		if (e[self->m_实例ID].m_Value) {
			box->m_背景绘制.f_setColor(self->m_实例ID + 1, S_UI主题::uic_菜单焦点色);
		}
		else {
			box->m_背景绘制.f_setColor(self->m_实例ID + 1, box->m_颜色A);
		}
		break;
	}
	case E_值类型::e_Type_UI32_FlagBits: {
		auto e = f_prop_UI32(box->m_Value);
		if ( (e & 1<<self->m_实例ID) == false) {
			box->m_背景绘制.f_setColor(self->m_实例ID+1, box->m_颜色A);
		}
		else {
			//box->m_背景绘制.f_setColor(self->m_实例ID, S_UI主题::uic_菜单焦点色);
		}
		break;
	}
	}

	
	return false;
}
static bool on_鼠标点击项(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_多选框* box = (C_多选框*)(self->m_父部件);

	switch (box->m_Value.m_Type) {
	case E_值类型::e_Type_Bool_1D: {
		auto e = f_prop_Bool_1D(box->m_Value);
		
		e[self->m_实例ID].m_Value = !(e[self->m_实例ID].m_Value);
		for (uint8 i = 0; i < box->m_Value.m_值元素个数; ++i) {
			//e[i].m_Value = false;
			if (e[i].m_Value) {
				box->m_背景绘制.f_setColor(i, S_UI主题::uic_菜单焦点色);
			}
			else {
				box->m_背景绘制.f_setColor(i, box->m_颜色A);
			}
		}
		//box->m_背景绘制.f_setColor(self->m_实例ID, S_UI主题::uic_菜单焦点色);
		break;
	}
	case E_值类型::e_Type_UI32_FlagBits: {
		auto e = f_prop_UI32(box->m_Value);

		if (e & (1 << self->m_实例ID)) {
			f_prop_UI32(box->m_Value) &= ((1 << self->m_实例ID) ^ 0xffffffff);
			box->m_背景绘制.f_setColor(self->m_实例ID+1, box->m_颜色A);
		}
		else {
			f_prop_UI32(box->m_Value) |= (1 << self->m_实例ID);
			box->m_背景绘制.f_setColor(self->m_实例ID+1, S_UI主题::uic_菜单焦点色);
		}
		break;
	}
	}

	if (box->m_Value.m_UI->m_Update) {
		box->m_Value.m_UI->m_Update(box->m_Value);
	}

	return false;
}

C_多选框::C_多选框(E_方向 dir, S_Props& Value, S_UI创建环境& ctx) : C_Widget(&ctx) {
	mf_布局Fun	= on_多选框布局;
	mf_DrawFun	= on_多选框Draw;
	mf_变换修改	= on_多选框变换修改;
	

	m_颜色A = S_UI主题::uic_按钮背景;
	m_方向 = dir;
	
	m_是否绘制图标 = true;
	m_是否绘制标题 = true;

	f_绑定数据(Value);
}

C_多选框::~C_多选框() {
}

void C_多选框::f_绑定数据(S_Props& prop) {
	uint32 num = m_子组件.size();
	m_Value = prop;

	uint32 元素个数 = 0;
	switch (m_Value.m_Type) {
	//case E_值类型::e_Type_Bool_Array1D: 
	case E_值类型::e_Type_Bool_1D: {
		元素个数 = prop.m_值元素个数;
		break;
	}
	case E_值类型::e_Type_UI32_FlagBits: {
		元素个数 = 32;
		m_间隔宽度 = 2;
		break;
	}
	}


	if (num > prop.m_值元素个数) {
		f_widget_remove子部件(this, prop.m_值元素个数, num);
	}
	else {
		for (uint32 i = num; i < 元素个数; ++i) {
			C_Widget* w = new C_Widget();
			w->mf_鼠标进入 = on_鼠标进入项;
			w->mf_鼠标离开 = on_鼠标离开项;
			w->mf_鼠标按键点击 = on_鼠标点击项;
			w->m_是否延展.x = true;
			w->m_是否延展.y = true;
			w->m_间隔宽度 = 1.5;
			w->m_实例ID = i;
			f_添加子组件(w);
		}
	}

	auto e = f_get更新部件();
	for (uint32 i = 0; i < 元素个数; ++i) {
		e.m_W[i]->m_实例ID = i;
	}
}



C_Widget* f_ui_创建多选框(S_UI创建环境& ctx, S_Props& prop, uint8 键码, E_方向 绘制方向) {
	C_多选框* box = new C_多选框(绘制方向, prop, ctx);
	prop.m_UI->m_部件 = box;
	return box;
}

void f_ui_bind多选框属性(C_Widget* self, S_Props& p, E_方向 方向) {
	assert(dynamic_cast<C_多选框*>(self));
	((C_多选框*)self)->f_绑定数据(p);
	((C_多选框*)self)->m_方向 = 方向;

	auto e = self->f_get更新部件();
	if (e.m_Num > 1) {
		if (方向 == E_方向::e_横向) {
			e.m_W[0]->m_图元 = S_Widget预设图元::m_左圆角矩形;
			e.m_W[e.m_Num - 1]->m_图元 = S_Widget预设图元::m_右圆角矩形;
		}
		else {
			e.m_W[0]->m_图元 = S_Widget预设图元::m_上圆角矩形;
			e.m_W[e.m_Num - 1]->m_图元 = S_Widget预设图元::m_下圆角矩形;
		}
	}
}








static vec2 g节点鼠标局部位置 = { 0,0 };
static float32 g控制点拾取大小 = 8;



static E_事件是否传递 on_曲线编辑视口准备拖动(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	g节点鼠标局部位置 = f_widget_get鼠标局部位置(鼠标.gPos, self);
	std::cout<<self->m_实例ID<<std::endl;
	return E_事件是否传递::e_事件传递_继续;
}

static E_事件是否传递 on_曲线编辑视口拖动(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	C_curve编辑视口* box = static_cast<C_curve编辑视口*>(self->m_父部件);

	vec2 相对于开始拖拽时鼠标相对组件偏移 = f_widget_get鼠标局部位置(鼠标.gPos, box);
	相对于开始拖拽时鼠标相对组件偏移.x -= g节点鼠标局部位置.x;
	相对于开始拖拽时鼠标相对组件偏移.y -= g节点鼠标局部位置.y;
	
	vec2 size = box->m_Size - g控制点拾取大小;
	if (相对于开始拖拽时鼠标相对组件偏移.x > size.x) 相对于开始拖拽时鼠标相对组件偏移.x = size.x;
	if (相对于开始拖拽时鼠标相对组件偏移.y > size.y) 相对于开始拖拽时鼠标相对组件偏移.y = size.y;
	if (相对于开始拖拽时鼠标相对组件偏移.x < 0) 相对于开始拖拽时鼠标相对组件偏移.x = 0;
	if (相对于开始拖拽时鼠标相对组件偏移.y < 0) 相对于开始拖拽时鼠标相对组件偏移.y = 0;
	
	self->f_setPos(相对于开始拖拽时鼠标相对组件偏移);

	vec2 相对偏移比例 = 相对于开始拖拽时鼠标相对组件偏移 / size;
	
	auto* curve = f_prop_2DCurve(box->m_Value);
	auto* point = f_an_get曲线点A(curve, self->m_实例ID);
	//std::cout<<self->m_实例ID<<std::endl;
	if (point) {
		相对偏移比例.y = 1.0 - 相对偏移比例.y;
		point->value = 相对偏移比例;
	}
	
	f_an_钳制曲线值排序(curve);
	f_an_钳制曲线自动控制点(curve);
	box->m_绘制属性更新 = true;

	return E_事件是否传递::e_事件传递_终止;
}

static bool on_曲线编辑视口结束拖放(C_Widget* self, C_Widget* 拾取的部件, S_拖放数据& data) {
	C_curve编辑视口* box = static_cast<C_curve编辑视口*>(self->m_父部件);

	if (!(self->m_开启渲染)) return true;

	auto* curve = f_prop_2DCurve(box->m_Value);

	//auto* point = f_an_get曲线点A(curve, self->m_实例ID);
	auto e = box->f_get更新部件();
	auto* point = f_an_get曲线点A(curve, self->m_实例ID);
	if (point && e.m_Num) {
		int32 id = f_an_移除曲线重合点(curve, point, 0.05);
		
		for (uint32 i = 0; i < e.m_Num; ++i) {
			if (e.m_W[i]->m_实例ID == id) {
				//std::vector<C_Widget*> ws = { self };
				//f_widget_remove子部件(box, ws, false);
				e.m_W[i]->m_开启渲染 = false;
				e.m_W[i]->f_setPos({ -1,-1 });
				e.m_W[i]->m_实例ID = -1;

				f_an_钳制曲线值排序(curve);
				f_an_钳制曲线自动控制点(curve);
				break;
			}
		}
	}

	f_prop_采样曲线拷贝到GPU(box->m_Value);
	//f_buf_gresize(box->m_Value.m_GPU缓存[0], curve->count);
	//for (uint32 i = 0; i < curve->count; ++i) {
	//	f_buf_曲线段_at(box->m_Value.m_GPU缓存[0], i) = curve->point[i];
	//}
	//f_buf_uVec2_at(box->m_Value.m_GPU缓存[1]) = { uint32(box->m_Value.m_GPU缓存[0].m_Mem.m_偏移), box->m_Value.m_GPU缓存[0].m_Mem.m_大小 };
	return true;
}

static bool on_曲线编辑视口控制点鼠标进入(C_Widget* self, const S_鼠标& 轮值) {
	C_curve编辑视口* box = static_cast<C_curve编辑视口*>(self->m_父部件);
	self->m_颜色A = { 255,255,200,255 };
	box->m_绘制属性更新 = true;
	std::cout<<self->m_实例ID<<std::endl;
	return false;
}

static bool on_曲线编辑视口控制点鼠标移出(C_Widget* self, const S_鼠标& 轮值) {
	C_curve编辑视口* box = static_cast<C_curve编辑视口*>(self->m_父部件);
	self->m_颜色A = { 150,150,150,255 };
	box->m_绘制属性更新 = true;
	return false;
}


static C_Widget* f_添加钳制曲线控制点组件(C_Widget* self) {
	C_Widget* 控制点 = new C_Widget(self->m_UIctx);
	控制点->mf_开始拖拽 = on_曲线编辑视口准备拖动;
	控制点->mf_拖拽 = on_曲线编辑视口拖动;
	控制点->mf_结束拖拽 = on_曲线编辑视口结束拖放;
	控制点->mf_鼠标进入 = on_曲线编辑视口控制点鼠标进入;
	控制点->mf_鼠标离开 = on_曲线编辑视口控制点鼠标移出;
	控制点->m_开启渲染 = true;

	控制点->f_setSize({ g控制点拾取大小, g控制点拾取大小 });
	self->f_添加子组件(控制点);
	return 控制点;
}


static bool on_曲线编辑视口添加控制点(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_curve编辑视口* box = static_cast<C_curve编辑视口*>(self);
	vec2 位置 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);
	
	auto* curve = f_prop_2DCurve(box->m_Value);

	static S_Gpu曲线拾取计算* pick = new S_Gpu曲线拾取计算(box->m_UIctx->m_Ctx);

	vec2 size = box->m_Size - g控制点拾取大小;
	位置 = vec_Max(位置, { 0,0 });
	位置 = vec_Min(位置, size);

	vec2 点偏移 = size;
	点偏移.x = (g控制点拾取大小 * 0.5) / 点偏移.x;
	点偏移.y = (g控制点拾取大小 * 0.5) / 点偏移.y;

	vec2 相对偏移比例 = 位置;
	相对偏移比例 = 位置 / size;
	相对偏移比例 -= 点偏移;
	相对偏移比例.y = 1.0 - 相对偏移比例.y;
	
	auto e = self->f_get更新部件();
	uint32 已使用点数量 = 0;
	for (uint32 i = 0; i < e.m_Num; ++i) {
		if (e.m_W[i]->m_开启渲染) {
			++已使用点数量;
		}
	}

	if (已使用点数量 > 2) {
		float32 minDis = 100000000;
		int32 点ID = -1;
		for (uint32 i = 0; i < curve->count - 1; ++i) {
			for (uint32 j = 0; j <= 32; ++j) {
				float muse_to_center_dis = f_curve_cal_toLineCenterDis(curve->point[i], curve->point[i + 1], 相对偏移比例, j, 0.02);
				if (muse_to_center_dis < 0.02) {
					if (muse_to_center_dis < minDis) {
						minDis = muse_to_center_dis;
						点ID = i;
					}
				}
			}
		}
		if (点ID < 0) {
			return true;
		}
	}
	//int32 点ID = pick->f_run(box->m_曲线绘制.m_曲线点, 相对偏移比例, 0.02);
	C_Widget* 控制点 = nullptr;
	uint32 i = 0;
	for (; i < 已使用点数量; ++i) {
		if (e.m_W[i]->m_开启渲染 == false) {
			控制点 = e.m_W[i];
			控制点->m_开启渲染 = true;
			控制点->m_实例ID = 已使用点数量;
			box->m_绘制属性更新 = true;
			break;
		}
	}
	if (!控制点) {
		控制点 = f_添加钳制曲线控制点组件(self);
		控制点->m_实例ID = 已使用点数量;
		控制点->m_开启渲染 = true;
	}
	控制点->f_setPos(位置);
	
	

	f_an_添加钳制曲线点(curve, 相对偏移比例, { 0,0 }, { 0,0 }, 控制点->m_实例ID);
	f_an_钳制曲线值排序(curve);
	f_an_钳制曲线自动控制点(curve);

	f_prop_采样曲线拷贝到GPU(box->m_Value);
	//f_buf_gresize(box->m_Value.m_GPU缓存[0], curve->count);
	//for (i = 0; i < curve->count; ++i) {
	//	f_buf_曲线段_at(box->m_Value.m_GPU缓存[0], i) = curve->point[i];
	//}
	//f_buf_uVec2_at(box->m_Value.m_GPU缓存[1]) = { uint32(box->m_Value.m_GPU缓存[0].m_Mem.m_偏移), box->m_Value.m_GPU缓存[0].m_Mem.m_大小 };

	return true;
}

static bool on_曲线采样框鼠标移动(C_Widget* self, const ivec4& value) {
	C_curve编辑视口* box = static_cast<C_curve编辑视口*>(self);

	vec2 位置 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);

	auto* curve = f_prop_2DCurve(box->m_Value);

	vec2 size = box->m_Size - g控制点拾取大小;
	位置 = vec_Max(位置, { 0,0 });
	位置 = vec_Min(位置, size);

	vec2 点偏移 = size;
	点偏移.x = (g控制点拾取大小 * 0.5) / 点偏移.x;
	点偏移.y = (g控制点拾取大小 * 0.5) / 点偏移.y;

	vec2 相对偏移比例 = 位置;
	相对偏移比例 = 位置 / size;
	相对偏移比例 -= 点偏移;
	相对偏移比例.y = 1.0 - 相对偏移比例.y;


	int32 minDisID = -1;
	if (curve->count > 1) {
		float32 minDis = 100000000;
		
		for (uint32 i = 0; i < curve->count; ++i) {

			for (uint32 j = 0; j <= 32; ++j) {
				float muse_to_center_dis = f_curve_cal_toLineCenterDis(curve->point[i], curve->point[i + 1], 相对偏移比例, j, 0.02);

				if (muse_to_center_dis < 0.02) {
					if (muse_to_center_dis < minDis) {
						minDis = muse_to_center_dis;
						minDisID = i;
					}
				}
			}
		}
	}
	if (minDisID >= 0) {
		box->m_线颜色 = { 30,30,30,255 };
	}
	else {
		box->m_线颜色 = { 10,10,10,255 };
	}



	box->m_Value.m_UI->m_Update(box->m_Value);
	//std::cout << "minDis = " << minDis << " " << minDisID << " " << minDisIDA << std::endl;
	return true;
}

static void on_曲线编辑视口布局(C_Widget* self, C_Widget** w, uint32 num) {
	C_curve编辑视口* box = static_cast<C_curve编辑视口*>(self);

	auto* curve = f_prop_2DCurve(box->m_Value);
	if(curve->count > num) return;

	for (uint32 i = 0; i < curve->count; ++i) {
		auto& 曲线点 = curve->point[i];
		
		vec2 pos = 曲线点.value;
		pos.y = 1.0 - pos.y;
		pos.x *= self->m_Size.x - g控制点拾取大小;
		pos.y *= self->m_Size.y - g控制点拾取大小;
		//std::cout << "相对于开始拖拽时鼠标相对组件偏移.x = " << pos.x << std::endl;
		w[曲线点.ID_Color.x]->f_setPos(pos);
		w[曲线点.ID_Color.x]->m_开启渲染 = true;
	}

}

static void on_曲线编辑视口绘制(C_Widget* self, S_2D画布* 画布) {
	C_curve编辑视口* box = static_cast<C_curve编辑视口*>(self);

	box->m_点绘制.m_属性 = f_vg_gen属性(画布);
	
	box->m_曲线绘制.m_属性 = f_vg_gen属性(画布);
	box->m_曲线绘制.f_Draw(画布, box->m_曲线绘制.m_属性);

	S_凸边图元 图元 = {};
	图元.属性 = f_vg_get属性指针(画布, box->m_点绘制.m_属性);
	box->m_点绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色填充);

}

static void on_曲线编辑视口变换(C_Widget* self) {
	C_curve编辑视口* box = static_cast<C_curve编辑视口*>(self);
	auto e = self->f_get更新部件();
	//vec2 loc = { 4, 4 };
	vec2 size = self->m_Size - g控制点拾取大小;
	auto* curve = f_prop_2DCurve(box->m_Value);


	S_2D顶点属性 属性;
	属性.m_偏移 = {};
	属性.m_比例 = {1,1};
	属性.m_渐变数量 = 0;
	属性.m_间隔 = 0;
	f_vg_set属性(self->m_画布, box->m_点绘制.m_属性, 属性);


	
	属性.m_偏移 = {};
	属性.m_比例 = size;
	属性.m_渐变数量 = curve->count - 2;
	属性.m_间隔 = 0;
	f_vg_set属性(self->m_画布, box->m_曲线绘制.m_属性, 属性);
	
	uint32 num = curve->count;

	box->m_点绘制.f_alloc(num);
	box->m_曲线绘制.f_begin(num);

	vec2 点偏移 = size;
	点偏移.x = (g控制点拾取大小 * 0.5) / 点偏移.x;
	点偏移.y = (g控制点拾取大小 * 0.5) / 点偏移.y;
	for(uint32 i = 0; i< num; ++i){
		auto 曲线点 = curve->point[i];

		曲线点.value.y = 1.0 - 曲线点.value.y;
		曲线点.L_point.y = 1.0 - 曲线点.L_point.y;
		曲线点.R_point.y = 1.0 - 曲线点.R_point.y;
		
		
		
		mat3X2 Mat;
		Mat.row0 = 曲线点.value * size + 0.5f;
		Mat.row1 = { 6,6 };
		Mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
		box->m_点绘制.f_set单色填充(i, Mat, e.m_W[曲线点.ID_Color.x]->m_颜色A, S_Widget预设图元::m_矩形);
		
		曲线点.value += 点偏移;
		曲线点.L_point += 点偏移;
		曲线点.R_point += 点偏移;
		曲线点.ID_Color.y = f_PackData4X8(box->m_线颜色);
		box->m_曲线绘制.f_setPoint(i, 曲线点);

	}
	box->m_曲线绘制.f_end();
}

C_curve编辑视口::C_curve编辑视口(S_UI创建环境& ctx) : C_Widget(&ctx) {
	mf_布局Fun = on_曲线编辑视口布局;
	mf_DrawFun = on_曲线编辑视口绘制;
	mf_变换修改 = on_曲线编辑视口变换;

	mf_鼠标按键点击 = on_曲线编辑视口添加控制点;
	mf_鼠标移动 = on_曲线采样框鼠标移动;

	m_Value = {};
	m_临时曲线数据 = f_core_array_new(0, sizeof(S_CurvePoint));

	m_线颜色 = { 10,10,10,255 };
}

C_curve编辑视口::~C_curve编辑视口(){
	f_core_array_free(m_临时曲线数据);
}



static void on_曲线采样框布局(C_Widget* self, C_Widget** w, uint32 num) {
	C_曲线采样框* box = static_cast<C_曲线采样框*>(self);

	vec2 loc = { 4, 4 };
	vec2 size = self->m_Size;
	size.x -= 8;
	size.y -= 34;

	box->ui曲线视口->f_setPos(loc);
	box->ui曲线视口->f_setSize(size);


	loc.y = self->m_Size.y - 24;
	size.y = 20;
	box->ui当前选中控制点->f_setPos(loc);
	box->ui当前选中控制点->f_setSize(size);

}

static void on_曲线采样框绘制(C_Widget* self, S_2D画布* 画布) {
	C_曲线采样框* box = static_cast<C_曲线采样框*>(self);

	box->m_背景绘制.m_属性 = f_vg_gen属性(画布);
	S_凸边图元 图元 = {};
	图元.属性 = f_vg_get属性指针(画布, box->m_背景绘制.m_属性);
	box->m_背景绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色填充);

	auto 字体 = f_surface_get字体(*self->m_UIctx, S_UI主题::ui_默认字体);
	box->m_文本绘制.f_Draw(画布, &字体, box->m_背景绘制.m_属性);
	box->m_图标绘制.f_Draw单色(画布, box->m_背景绘制.m_属性, S_UI主题::ui_默认图标);

}

static void on_曲线采样框变换(C_Widget* self) {
	C_曲线采样框* box = static_cast<C_曲线采样框*>(self);

	auto ws = self->f_get更新部件();
	//auto* curve = f_prop_Curve(box->m_Value);
	const auto& 字体 = f_surface_get字体库(*self->m_UIctx, S_UI主题::ui_默认字体);
	
	box->m_背景绘制.f_alloc(2);
	mat3X2 Mat;
	Mat.row0 = {};
	Mat.row1 = self->m_Size;
	Mat.row2 = { S_UI主题::ui_面板圆角半径 * 2, 0 };
	box->m_背景绘制.f_set单色填充(0, Mat, S_UI主题::uic_深灰, S_Widget预设图元::m_圆角矩形);

	Mat.row0 = ws.m_W[0]->m_Pos;
	Mat.row1 = ws.m_W[0]->m_Size;
	Mat.row2 = { S_UI主题::ui_面板圆角半径, 0 };
	box->m_背景绘制.f_set单色填充(1, Mat, S_UI主题::uic_灰色, S_Widget预设图元::m_圆角矩形);


}

C_曲线采样框::C_曲线采样框(S_UI创建环境& ctx) : C_Widget(&ctx) {
	mf_布局Fun = on_曲线采样框布局;
	mf_DrawFun = on_曲线采样框绘制;
	mf_变换修改 = on_曲线采样框变换;

	f_setSize({ 256,150 });
	
	m_当前选中控制点 = f_alloc_Vec2Prop(nullptr, L"控制点");
	f_prop_Vec2(m_当前选中控制点) = { 0,0 };

	ui当前选中控制点 = new C_Vec(E_方向::e_横向, m_当前选中控制点, ctx);
	ui曲线视口 = new C_curve编辑视口(ctx);

	f_添加子组件(ui曲线视口);
	f_添加子组件(ui当前选中控制点);
}

C_曲线采样框::~C_曲线采样框() {
}

C_Widget* f_ui_创建曲线采样器(S_UI创建环境& ctx) {
	C_曲线采样框* box = new C_曲线采样框(ctx);

	return box;
}

void f_ui_曲线采样器绑定属性数据(C_Widget* self, S_Props& prop) {
	C_curve编辑视口* curve_view = static_cast<C_曲线采样框*>(self)->ui曲线视口;
	curve_view->m_Value = prop;

	auto* curve = f_prop_2DCurve(curve_view->m_Value);
	vec2 size = curve_view->m_Size - g控制点拾取大小;
	uint32 num = curve->count;

	
	f_widget_remove所有子部件(curve_view, false);
	
	for (uint32 i = 0; i < num; ++i) {
		C_Widget* 控制点 = f_添加钳制曲线控制点组件(curve_view);
		
		控制点->m_开启渲染 = true;
		控制点->m_实例ID = i;
		控制点->f_setPos(curve->point[i].value * size);
		curve->point[i].ID_Color.x = i;

		//f_buf_曲线段_at(prop.m_GPU缓存[0], i) = curve->point[i];
	}
	//f_buf_uVec2_at(prop.m_GPU缓存[1]) = { uint32(prop.m_GPU缓存[0].m_Mem.m_偏移), prop.m_GPU缓存[0].m_Mem.m_大小 };
	if (prop.m_GPU缓存[0].m_Buf) f_buf_gresize(prop.m_GPU缓存[0], num);
	f_prop_采样曲线拷贝到GPU(curve_view->m_Value);


	curve_view->m_绘制属性更新 = true;
	self->m_绘制属性更新 = true;
	
}








C_多曲线编辑框::C_多曲线编辑框(S_UI创建环境& ctx) {
}

C_多曲线编辑框::~C_多曲线编辑框() {
}







S_Gpu曲线拾取计算::S_Gpu曲线拾取计算(S_设备环境& ctx) {
	std::vector<S_着色器创建参数> 参数配置;

	参数配置 = {
		{DEF_BINDING_WIDGET_CurvePoint, E_着色阶段::e_计算着色, E_板载缓存类型::e_SSBO},
		{DEF_BINDING_WIDGET_CurvePick, E_着色阶段::e_计算着色, E_板载缓存类型::e_SSBO},
		{DEF_BINDING_WIDGET_CurvePickID, E_着色阶段::e_计算着色, E_板载缓存类型::e_SSBO},
	};

	m_GpuCtx = f_gpu_create并行计算实例(ctx, S_引擎::m_UI着色器文件根路径 + "UI曲线拾取.spv", 参数配置);

	//m_相交数据 = f_buf_create板载缓存(*m_GpuCtx->m_Ctx, E_板载缓存类型::e_SSBO, sizeof(vec2));
	//S_Gpu实例拾取信息 拾取属性参数 = { mat, s, dir };S_CurvePick
	//f_buf_fill板载缓存(拾取属性, &拾取属性参数, sizeof(S_GpuPick));
	m_参数元素[0] = nullptr;
	m_参数元素[1] = f_buf_create板载缓存(m_GpuCtx->m_Ctx, sizeof(S_CurvePick), E_板载缓存类型::e_SSBO, 1);
	m_参数元素[2] = f_buf_create板载缓存(m_GpuCtx->m_Ctx, E_板载缓存类型::e_SSBO, sizeof(vec2));
	//m_参数元素[2] = m_相交数据;

	m_布局位置[0] = DEF_BINDING_WIDGET_CurvePoint;
	m_布局位置[1] = DEF_BINDING_WIDGET_CurvePick;
	m_布局位置[2] = DEF_BINDING_WIDGET_CurvePickID;

}

int32 S_Gpu曲线拾取计算::f_run(S_板载缓存* 曲线控制点, vec2 拾取坐标, float32 最小距离) {
	if (曲线控制点->m_Size < 2) return -1;

	uvec3 dim = { 1,1,1 };
	m_参数元素[0] = 曲线控制点;

	dim.x = 曲线控制点->m_Size - 1;

	S_CurvePick* pick = f_buf_map板载缓存<S_CurvePick>(m_参数元素[1]);
	pick->pick_coord = 拾取坐标;
	pick->pick_dis.x = 最小距离;
	f_buf_unmap板载缓存(m_参数元素[1]);


	f_buf_resize(m_参数元素[2], 曲线控制点->m_Size);


	f_setGPU参数布局(m_GpuCtx, { m_参数元素, nullptr, m_布局位置, 3, 0 });

	f_GPU_run计算(m_GpuCtx, dim);

	vec2* 拾取距离 = f_buf_map板载缓存<vec2>(m_参数元素[2]);
	for (uint32 i = 0; i < dim.x; ++i) {
		std::cout << "拾取距离 = "<< i << " : " << 拾取距离[i].x << " " << 拾取距离[i].y << std::endl;
	}
	f_buf_unmap板载缓存(m_参数元素[2]);
	return int32();
}



